package com.chejianer.push.service;


import com.chejianer.core.domain.entity.cms.BannerCarousel;
import com.chejianer.core.utils.Constants;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

public interface KeyValueService {

    long setNX(String key, String value, int expire);

    void put(String key, String value);

    // expire: seconds
    void put(String key, int expire, String value);

    String get(String key);

    <T> T getOrDefault(String key, T defaultValue);

    <T> T getOrDefault(String key, T defaultValue, int expire);

    <T> T getOrDefaultSystemVariable(String key, T defaultValue);

    <T> T getOrDefaultSystemVariable(String key, T defaultValue, int expire);

    default void del(String key) {
        del(key, 0);
    }

    void del(String key, int dbIndex);

    @SuppressWarnings("unused")
    void putObj(String key, Object obj);

    void putObj(String key, int expire, Object obj);

    // Object getObj(String key);
    <T> T getObj(String key, Class<T> tClass);

    default void setAdd(String key, Collection<?> objects) {
        setAdd(key, objects, Constants.TIME_OF_ONE_DAY);
    }

    void setAdd(String key, Collection<?> objects, int expire);

    Set<BannerCarousel> getAllBanner();

    boolean exists(String key);

    void expire(String key, int second);

    Map<String, Map<String, Long>> matchKey(String prefix, String suffix);

    Integer delMatchedKeys(String keyPrefix, String suffix);

    /**
     * insert map pattern<String,Object> to redis cache
     *
     * @param key      redis key
     * @param hashData hashmap
     */
    void addHash(String key, Map<String, ?> hashData);

    /**
     * add element to redis hashmap（ this map must exists）
     *
     * @param key        redis key
     * @param elementKey map key
     * @param data       map value
     */
    void addHashValue(String key, String elementKey, Object data);

    /**
     * get hashmap from redis cache
     *
     * @param key    redis key
     * @param tClass reflection source class name
     * @param <T>    reflection source class type
     * @return reflected map
     */
    <T> Map<String, T> getHash(String key, Class<T> tClass);

    /**
     * get element from redis cached map
     *
     * @param hashKey redis key
     * @param mapKey  map key
     * @param tClass  reflection source class name
     * @param <T>     reflection source class value
     * @return reflected object
     */
    <T> T getHashValue(String hashKey, String mapKey, Class<T> tClass);

    /**
     * remove element from hashmap
     *
     * @param hashKey redis key
     * @param mapKey  mapkey
     */
    void removeHashValue(String hashKey, String mapKey);

    void saveExceptionLog(Exception e, String orderNo);
}
